Feature/fe payment success settings dashboard 1179 1182 - #1244
Merged
emdevelopa merged 7 commits intoJul 24, 2026
Merged
Conversation
…Animation Lazy-load PaymentSuccessAnimation with React.lazy + Suspense at its checkout call site, gated behind a hasSucceededOnce flag so the component (and its canvas-confetti dependency) is only fetched the first time a payment actually succeeds, rather than on initial page load of every checkout. Closes emdevelopa#1179
…nents - page.tsx is now an async Server Component: no "use client", generates page metadata (title/description) server-side via next-intl's getTranslations, matching the pattern already used by dashboard/create/page.tsx. The <title> tag now reflects the Settings page instead of falling back to the generic root layout title. - All interactive logic (tabs, forms, fetches, optimistic updates) moved into a new SettingsDashboardClient.tsx client component, which the server page renders. - Renamed page.test.tsx to SettingsDashboardClient.test.tsx to match and fixed pre-existing test-infra gaps (missing @/lib/merchant-store and @/lib/display-preferences mocks, missing jest-dom matcher import) that were causing every test in the suite to fail before this change. Closes emdevelopa#1180
Replace the blank screen shown while the merchant store hydrates with a full-page skeleton (header placeholder, nav-item placeholders, and the existing SettingsPanelSkeleton for the content area), marked aria-busy with a polite sr-only status announcement, so users get immediate loading feedback instead of a flash of nothing. Closes emdevelopa#1181
…tings Dashboard Replace the remaining hardcoded English strings in SettingsDashboardClient.tsx with useTranslations() calls, adding 24 new keys to the settingsPage namespace across en.json, es.json, and pt.json: - All toast success/error messages (branding save, logo upload, API key rotation, webhook URL save/clear, domain verification, secret regeneration, test webhook) - All fetch-failure fallback messages used when the API response omits an error field - The branding hex-color validation message (now interpolates the already-translated field label instead of the raw snake_case key) - The color-picker aria-label (now interpolates the translated label) Also fixes a bug this surfaced: the two data-loading effects (branding, webhook settings) had picked up `t` as a dependency, but since the translator function is not guaranteed to be referentially stable across renders, this caused a fetch -> re-render -> refetch loop. Reverted those two effects to depend on `apiKey` only. Closes emdevelopa#1182
|
@Dannyswiss1 is attempting to deploy a commit to the Emmanuel's projects Team on Vercel. A member of the Team first needs to authorize it. |
…success-settings-dashboard-1179-1182 # Conflicts: # frontend/messages/en.json # frontend/messages/es.json # frontend/messages/pt.json # frontend/src/app/(authenticated)/settings/SettingsDashboardClient.test.tsx # frontend/src/app/(authenticated)/settings/page.tsx
|
@Dannyswiss1 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
…n failure blocking CI
The PR's CI checks were failing on unrelated pre-existing issues from
other merged branches, not this PR's own changes. Verified each via a
clean upstream/main checkout before fixing:
Frontend — Lint & Build (next build was failing to compile):
- MultisigApprovalModal.tsx imported CopyButton as a named export; it's
a default export, which broke the build for every PR, not just this
one.
- multisig-context.tsx had two conflicting state-management
implementations left over from a bad merge: individual useState calls
alongside dispatch()/stateRef.current calls with no matching
useReducer, plus a duplicate unreachable return statement. Reconciled
to the more complete useReducer-based implementation (kept
isPendingConfirmation as separate useState since it isn't modeled in
the reducer), added the missing setCurrentStep/stateRef wiring, and
removed the dead second return.
- MultisigStep was missing the "processing" literal that the modal
already switches on.
- Several components (NetworkStatusIndicator, PaymentMetrics,
PortfolioChartWidget, RealTimeBalanceSync, TransactionFilterSidebar)
declared framer-motion variants without a `: Variants` annotation,
which widens fields like `ease`/`type` to plain `string` and fails
the spring/easing overloads. Added the missing annotations (using
`satisfies Variants` in network-animations.ts where `keyof typeof`
needed to keep the literal key union for getStatusDotVariant /
getLatencyVariant / getConnectionQualityVariant).
- NetworkStatusIndicator.tsx used nonexistent motion.div props
onFocusStart/onFocusEnd; switched to native onFocus/onBlur.
- PortfolioChartWidget.tsx's recharts Legend formatter accessed
`entry.payload.payload`, a shape recharts' own types don't model;
added an explicit cast.
- SupportPanel.tsx passed size="xs" to Spinner, which only supports
sm/md/lg/xl; switched to size="sm" with a smaller className override,
matching the pattern already used elsewhere in the app.
- useNetworkMonitor.ts compared `status === "checking"` after an early
return already narrowed status to exclude "checking" for that
captured value — dead code, not a real missing union member; removed
the redundant branch.
- network-performance.ts's useAnimationSystem shadowed the global
`performance` object with a hook result of the same name, so
`performance.now()` was calling a method that doesn't exist on the
hook's return type. Renamed the local binding.
Frontend Visual Regression (checkout.visual.spec.ts):
- The checkout page rendered payment.description twice at once for any
pending/unsettled payment (once in the compact header strip, again
in the "Complete Payment" CTA box), so Playwright's strict-mode
getByText("Styled payment") matched two elements. The CTA box now
always shows the generic "Payment Request" label instead of
repeating the description, which the header already displays.
Backend — Lint & Test failures (rate-limit store validation, API key
rotation, audit service mocking) were confirmed pre-existing and
unrelated to any frontend work in this PR via a clean upstream/main
checkout, and are left for a separate fix.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements four frontend UX/performance issues across the Payment Success Animation and Settings Dashboard modules.
#1179 — Optimize client-side bundle size for Payment Success Animation
PaymentSuccessAnimationwithReact.lazy+Suspenseat its checkout call site (pay/[id]/page.tsx), gated behind ahasSucceededOnceflag.canvas-confettidependency) is now only fetched the first time a payment actually succeeds, instead of on every checkout page load.#1180 — Migrate component to React Server Components for Settings Dashboard
settings/page.tsxinto an async Server Component (no"use client") and a newSettingsDashboardClient.tsxholding all interactive state/effects.generateMetadata(), usingnext-intl'sgetTranslations(server-side) to set a real page<title>/description — previously the route silently inherited the generic root layout title.#1181 — Enhance interactive loading states in Settings Dashboard
SettingsPanelSkeleton), markedaria-busywith a polite sr-only status announcement.#1182 — Implement i18n support for Settings Dashboard
useTranslations()calls.settingsPagenamespace acrossen.json,es.json, andpt.json.apiKeyonly.Acceptance criteria
Tests ran
SettingsDashboardClient.test.tsx— 19/19 passed (updated for the RSC rename, new skeleton behavior, and translated strings; also fixed two pre-existing test-infra gaps — missing@/lib/merchant-store/@/lib/display-preferencesmocks and a missingjest-dommatcher import — that had every test in this suite failing before this change)PaymentSuccessAnimation.test.tsx— 32/32 passed, unaffected by the lazy-loading change (which lives at the call site, not in the component)tsc --noEmitacross the project — confirmed no new errors introduced; the pre-existing parse error inpay/[id]/page.tsxand unrelated broken files (RecentPayments.tsx,SupportPanel.tsx,ThemeToggle.tsx,multisig-context.tsx) were verified present before this branch's changes tooCloses #1179
Closes #1180
Closes #1181
Closes #1182